Optimize protobuf encoding and add CI performance reports - #4
Conversation
Port measured WKT, numeric map-key, uint64 buffer, and descriptor caching improvements. Fix deprecated fields and escaped custom names across codecs, preserve map-key behavior under writer settings, and add regression tests, JMH coverage, allocation budgets, and performance evidence.
Build base and candidate with the same JDK and shared benchmark inputs on Java 21 and 25. Keep throughput signals advisory, enforce complete allocation data, and publish validated reports from a separate trusted workflow.
First full CI performance reportPerformance run: passed on Java 21 and 25. All 60 base/head comparisons were validated against the raw JMH results. Each JVM comparison clean-built both revisions with the same compiler and benchmark inputs, then measured both on one runner.
Observed changes across the two within-JVM comparisons:
These are advisory signals, not a universal speedup or a proof that smaller regressions are absent. A timing signal requires at least 10% change and non-overlapping JMH 99.9% intervals. The existing 14 absolute allocation budgets, build, and official conformance job also passed on this commit. Both jobs used two forks, 3 × 1s warmup, 4 × 1s measurement, one thread, a 256 MiB heap, and the GC profiler. Java 21 ran on AMD EPYC 9V74; Java 25 ran on AMD EPYC 7763. Each base/head pair shared its runner; absolute throughput must not be compared between JVM jobs. Raw results, environment, build logs, and reports are available in the workflow artifacts for 90 days. This first report is posted manually because GitHub starts the automatic publisher only after its workflow exists on Java 21: all 30 comparisonsJava 21 performanceBase: cb106d5 → candidate: 2facf0a Throughput alerts are advisory. Existing allocation budgets are enforced separately.
Java 25: all 30 comparisonsJava 25 performanceBase: cb106d5 → candidate: 2facf0a Throughput alerts are advisory. Existing allocation budgets are enforced separately.
|
Protobuf WKT encoding performs avoidable reflective reads, and numeric map keys allocate temporary strings. This PR uses concrete WKT getters and direct quoted numeric-key writes, fixes codec edge cases, and adds repeatable CI comparisons so future PRs and default-branch pushes report their performance impact.
Encoding changes
The full same-compiler CI comparison on Java 21/25 measured Struct throughput +95–116%, codegen/typed maps +12–29%, and reflection Timestamp +25–29%. Struct allocations fell about 44%; map allocations fell 26–39% across all paths. Of 60 comparisons, 31 show improvement signals, 29 are inconclusive, and none show regression signals or allocation growth alerts. These are per-workload advisory signals, not an overall application speedup. Full CI results and raw artifacts supersede the earlier mixed-compiler follow-up; the historical local reports and compact CSV evidence remain in
docs/performance-port-2026-09-05.mdanddocs/performance-results/.Performance CI
main, using stock JMH on Java 21 and 25.workflow_runpublisher validates JSON artifacts, adds commit checks, and updates one PR comment while rejecting stale results. It never executes PR/artifact code with write credentials.The publisher starts automatically once its workflow exists on
main. This introducing PR already gets measurement job summaries and artifacts. No external account, JMH fork, branch-protection change, or paid runner is required.docs/performance-ci.mdcompares GitHub-native reporting, dedicated runners, CodSpeed, Bencher, and github-action-benchmark and explains protocol/limits.Validation
-Werror.Context reuse, packed field names, primitive-list rewrites, and CodSpeed infrastructure remain deferred.